import json
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet

from .models import Company
from utils.plugins import FormatUUID, to_dict_list, IsNoneOrWhitespace, remove_empty_keys, to_json
from utils.response import CustomRender
from rest_framework.decorators import action
from django.db.models import Q

# 使用装饰器使用自定义渲染器
"""
https://blog.csdn.net/vincent0920/article/details/136469038
修饰器使用范围
1. 请求方式         api_view
2. 返回数据格式     renderer_classes
3. 事务处理         
5. 权限验证         
6. 日志记录         
"""

# 视图类
class CompanyView(ViewSet):
    # renderer_classes = [CustomRender, BrowsableAPIRenderer]
    renderer_classes = [CustomRender]       # 自定义返回数据格式
    http_method_names = ['get', 'post']     # 自定义限制请求方式

    # 获取所有
    @action(methods=['get'], detail=False, url_path='get-all')
    def get_all(self, request):
        objs = Company.objects.filter(IS_DELETED=False)
        return Response(to_json(objs), status=status.HTTP_200_OK)

    # 获取详情
    @action(methods=['get'], detail=False, url_path='get-detail')
    def get_detail(self, request):
        # 获取UUID
        uuid = request.GET['id']
        if IsNoneOrWhitespace(uuid):
            raise ValueError("公司唯一编号不能为空")
        obj = Company.objects.get(ID=uuid)
        if obj.IS_DELETED is True:
            raise ValueError("记录为【%s】的数据已删除" % uuid)
        return Response(obj.to_dict(), status=status.HTTP_200_OK)

    # 条件查询
    @action(methods=['get'], detail=False, url_path='get-list')
    def get_list(self, request):
        params = request.GET.dict()
        # 查询谓词使用
        filter_dict = dict(NAME__icontains=params.get('name'), CODE__icontains=params.get('code'),
                           SHORT_NAME__icontains=params.get('shortName'), REMARK__icontains=params.get('remark'))
        companies = Company.objects.filter(IS_DELETED=False, **remove_empty_keys(filter_dict))
        return Response(to_json(companies), status=status.HTTP_200_OK)

    # 创建公司信息
    @action(methods=['post'], detail=False, url_path='create')
    def create_company(self, request):
        # 传入数据解析与获取
        body = json.loads(request.body)
        code = body.get('code')
        name = body.get('name')
        # 非空字段验证
        if IsNoneOrWhitespace(code):
            raise ValueError('公司编码不能为空')
        if IsNoneOrWhitespace(name):
            raise ValueError('公司名称不能为空')
        # 编码和名字重复认证=>需要进行查询
        objs = Company.objects.filter(Q(NAME=name) | Q(CODE=code))
        if objs.count() > 0:
            raise ValueError('公司编码或名称已存在')
        # 数据添加进入数据库
        company = Company.objects.create(
            ID=FormatUUID(),
            NAME=body.get('name'),
            CODE=body.get('code'),
            SHORT_NAME=body.get('shortName'),
            REMARK=body.get('remark')
        )
        # 返回数据处理：需要返回新增的数据信息
        return Response(company.to_dict(), status=status.HTTP_200_OK)

    # 修改公司信息
    @action(methods=['post'], detail=False, url_path='update')
    def update_company(self, request):
        # 传入数据解析与获取
        body = json.loads(request.body)
        com_id = body.get('id')
        code = body.get('code')
        name = body.get('name')
        # 非空字段验证
        if IsNoneOrWhitespace(com_id):
            raise ValueError('公司唯一编号不能为空')
        if IsNoneOrWhitespace(code):
            raise ValueError('公司编码不能为空')
        if IsNoneOrWhitespace(name):
            raise ValueError('公司名称不能为空')
        # 查询当前ID数据是否存在
        company = Company.objects.get(ID=com_id)
        if company.IS_DELETED is True:
            raise ValueError("记录为【%s】的数据已删除" % com_id)
        # 编码和名字重复认证=>需要进行查询
        objs = Company.objects.filter(~Q(ID=com_id) & (Q(NAME=name) | Q(CODE=code)))
        if objs.count() > 0:
            raise ValueError('公司编码或名称已存在')
        # 更新
        company.CODE = code
        company.NAME = name
        company.SHORT_NAME = body.get('shortName')
        company.REMARK = body.get('remark')
        company.save()
        return Response(company.to_dict(), status=status.HTTP_200_OK)

    # 批量删除公司
    @action(methods=['post'], detail=False, url_path='delete-list')
    def delete_company(self, request):
        body = json.loads(request.body)
        # 判断传入参数是否为ID列表
        if type(body) is list:
            companies = Company.objects.filter(ID__in=body, IS_DELETED=False)
            # 存在已删除数据的判断
            if companies.count() < len(body):
                raise ValueError("存在已删除的记录")
            count = companies.update(IS_DELETED=True)
            # companies.save() # 单个更新需要调用，批量更新不需要
            return Response({'count': count}, status=status.HTTP_200_OK)
        else:
            raise ValueError("传入的数据出现错误")

"""
# 单个获取
def get_view(request, uuid: str):
    # 采用model_to_dict方法返回数据缺少时间字段
    # from django.forms.models import model_to_dict
    # 查询的结果如果不是一个，报错：>1或0都不行
    obj = Company.objects.get(ID=uuid)
    if obj.IS_DELETED is False:
        raise ValueError("记录为【%s】的数据已删除" % uuid)
    return Response(obj.to_dict(), status=status.HTTP_200_OK)

# 条件查询
def get_list_view(request):
    '''
    # 1. 解析URL
    # url = urlparse(request.get_full_path())
    # 2. 获取URL的query参数,转换字典
    # prams = parse_qs(url.query)
    # 通过 request.GET.dict() 获取
    '''
    params = request.GET.dict()
    # 查询谓词使用
    filter_dict = {
        'CODE__icontains': params.get('code'),
        'NAME__icontains': params.get('name'),
        'SHORT_NAME__icontains': params.get('shortName'),
        'REMARK__icontains': params.get('remark')
    }
    companies = Company.objects.filter(IS_DELETED=False, **remove_empty_keys(filter_dict))
    print(companies.query)
    return Response(to_dict_list(companies), status=status.HTTP_200_OK)

# 新增
def createView(request):
    # 传入数据解析与获取
    body = json.loads(request.body)
    code = body.get('code')
    name = body.get('name')
    # 非空字段验证
    if IsNoneOrWhitespace(code):
        raise ValueError('公司编码不能为空')
    if IsNoneOrWhitespace(name):
        raise ValueError('公司名称不能为空')
    # 编码和名字重复认证=>需要进行查询
    objs = Company.objects.filter(Q(NAME=name) | Q(CODE=code))
    if objs.count() > 0:
        raise ValueError('公司编码或名称已存在')
    # 数据添加进入数据库
    company = Company.objects.create(
        ID=FormatUUID(),
        NAME=body.get('name'),
        CODE=body.get('code'),
        SHORT_NAME=body.get('shortName'),
        REMARK=body.get('remark')
    )
    # 返回数据处理：需要返回新增的数据信息
    return Response(company.to_dict(), status=status.HTTP_200_OK)

# 更新
def update_view(request):
    # 传入数据解析与获取
    body = json.loads(request.body)
    com_id = body.get('id')
    code = body.get('code')
    name = body.get('name')
    # 非空字段验证
    if IsNoneOrWhitespace(com_id):
        raise ValueError('公司唯一编号不能为空')
    if IsNoneOrWhitespace(code):
        raise ValueError('公司编码不能为空')
    if IsNoneOrWhitespace(name):
        raise ValueError('公司名称不能为空')
    # 查询当前ID数据是否存在
    company = Company.objects.get(ID=com_id)
    if company.IS_DELETED is True:
        raise ValueError("记录为【%s】的数据已删除" % com_id)
    # 编码和名字重复认证=>需要进行查询
    objs = Company.objects.filter(~Q(ID=com_id) & (Q(NAME=name) | Q(CODE=code)))
    if objs.count() > 0:
        raise ValueError('公司编码或名称已存在')
    # 更新
    company.CODE = code
    company.NAME = name
    company.SHORT_NAME = body.get('shortName')
    company.REMARK = body.get('remark')
    company.save()
    return Response(company.to_dict(), status=status.HTTP_200_OK)

# 列表删除（返回删除的数量）==> 修改IS_DELETED数据(伪删除)
def delete_list_view(request):
    body = json.loads(request.body)
    # 判断传入参数是否为ID列表
    if type(body) is list:
        companies = Company.objects.filter(ID__in=body, IS_DELETED=False)
        # 存在已删除数据的判断
        if companies.count() < len(body):
            raise ValueError("存在已删除的记录")
        count = companies.update(IS_DELETED=True)
        # companies.save() # 单个更新需要调用，批量更新不需要
        return Response({'count': count}, status=status.HTTP_200_OK)
    else:
        raise ValueError("传入的数据不是列表格式")
"""
